Setting up CI CD for Developers
This tutorial will guide you through the steps to set up a project on the ABAIR CI/CD pipeline. As an example, it uses a node application with the name ABAIR_APP_X.
Prerequisites:
-
Server:
- You have a key for your project to SSH into the services VM.
- An Admin has set up a directory for your project with a deployment script.
-
Github:
- You are a member of the Phonetics & Speech Lab Github Organisation.
- You have created a remote Git repository on Github for
ABAIR_APP_X - You have initialised a local Git repository and linked it to the remote.
-
Docker:
- You have Docker installed on your local machine.
- You have a Dockerfile in the root of your project that successfully builds an image of your application.
- This image can be run locally using Docker and accessed over the specified open port.
- You have been given the Docker Password for the registry.
Steps
1. Add CI/CD Github Actions to your project
Create a .github/workflows/ folder in the root of your project and add the following 2 files
ci.yml
name: Node.js CI
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js LTS
uses: actions/setup-node@v3
with:
node-version: 18.16.0
- run: |
npm i
cd.yml
name: Publish Docker image
on:
push:
branches:
- main
jobs:
push_to_registry:
name: Push Docker image to Docker Registry
runs-on: ubuntu-latest
environment: prod
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: registry.abair.ie:5000/${{ vars.PROJECT_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
update_ssh:
name: Update running software
needs: "push_to_registry"
runs-on: ubuntu-latest
environment: prod
steps:
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ vars.HOST }}
username: ${{ vars.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ vars.PORT }}
script: bash ${{ vars.DEPLOY_SCRIPT_PATH }}
2. Generate SSH Private Key
Recommended: Use the generate-ssh-key.sh script which automates the steps below.
- Sign into the Services VM as a sudo user.
- Sign into the services account using
sudo su services. - Run the following command to generate the SSH key. Make sure to replace ABAIR_APP_X with the name of your app.
ssh-keygen -t ed25519 -a 100 \
-C "ABAIR_APP_X Github Action" \
-f ~/.ssh/ABAIR_APP_X_ed25519 \
-N ""
- Add the public key to
authorized_keysso the Services VM accepts connections using this key:
cat ~/.ssh/ABAIR_APP_X_ed25519.pub >> ~/.ssh/authorized_keys
- Copy the private key contents to the GitHub
prodenvironment secrets asSSH_PRIVATE_KEY:
cat ~/.ssh/ABAIR_APP_X_ed25519
Copy the entire output (including -----BEGIN OPENSSH PRIVATE KEY----- and -----END OPENSSH PRIVATE KEY-----).
3. Create Environment and Set Secrets/Variables
On the Github page for ABAIR_APP_X:
3.1 Create the prod Environment
- Navigate to
Settings→Environments - Click
New environment - Name it
prodand clickConfigure environment
3.2 Add Environment Secrets
In the prod environment settings, under Environment secrets, add:
| Name | Value |
|---|---|
| DOCKER_PASSWORD | (provided by Admin) |
| SSH_PRIVATE_KEY | Private SSH key from the services user in the Services VM |
3.3 Add Environment Variables
In the prod environment settings, under Environment variables, add:
| Name | Value |
|---|---|
| PROJECT_NAME | ABAIR_APP_X |
| DOCKER_REGISTRY | registry.abair.ie:5000 |
| DOCKER_USERNAME | admin |
| HOST | srv.abair.ie |
| USERNAME | services |
| PORT | 22102 |
| DEPLOY_SCRIPT_PATH | /home/services/ABAIR_APP_X/deploy-ABAIR_APP_X.sh |
4. Deploy Script
Add the following deploy script to the base of your project for reference. It will be copied by Admin to the Services VM
deploy-ABAIR_APP_X.sh
docker stop ABAIR_APP_X
docker rm ABAIR_APP_X
docker login 10.0.0.2:5000 -u admin -p {see elsewhere}
docker rmi 10.0.0.2:5000/ABAIR_APP_X:main
docker pull 10.0.0.2:5000/ABAIR_APP_X:main
docker run -t -d -p port:port --restart always --name project-name 10.0.0.2:5000/ABAIR_APP_X:main
FAQ
The CI/CD Fails when I add supabase to my project
Solution
- Add the following to the Dockerfile of your project before
RUN npm run build
ARG NEXT_PUBLIC_SUPABASE_URL
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
- Update the cd.yml file to include the following in the "Build and push Docker image" step (the failing step).
build-args: |
NEXT_PUBLIC_SUPABASE_URL=${{ vars.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY=${{ vars.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
- In the GitHub project:
- Go to: Settings -> Environments -> prod -> Environment variables
- Add the supabase url (NEXT_PUBLIC_SUPABASE_URL) and anon key (NEXT_PUBLIC_SUPABASE_ANON_KEY) variables. These can be found in the supabase project settings.
Failing to authorize using publickey
Follow this carefully.
- Make sure your private SSH key is pasted correctly into the GitHub
prodenvironment secrets asSSH_PRIVATE_KEY. You must copy all contents of the file. - Make sure that your ssh key file is named correctly (ABAIR_APP_X_ed25519).
- Make sure that your public ssh key is added to authorized keys.